package team.first.movieapiv2pro.interceptor;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import team.first.movieapiv2pro.token.Token;
import team.first.movieapiv2pro.token.TokenType;
import team.first.movieapiv2pro.util.JWTHS256;
import team.first.movieapiv2pro.vo.ApiResponse;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;
import java.util.Date;

/**
 * @Author: HAPPY
 * @Project_name: project
 * @Package_name: team.first.movieapiv1pro.interceptor
 * @Date: 2021/12/24 15:44
 * @Description:
 */
@Component
public class AuthorizationInterceptor implements HandlerInterceptor {

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 客户端请求头里的token
        String token = request.getHeader("token");
        // token认证结果
        int flag = 0;
        ApiResponse<Token> apiResponse = new ApiResponse<>();

        // 如果token不为空
        if (token != null) {
            // 有token，将token转为对象
            Token userToken;

            try {
                // 可能会出异常，加个 try catch
                userToken = JSON.parseObject(token, Token.class);

                // 判断token是否合法
                // 检查缓存里是否有这个token
                String tokenValue = stringRedisTemplate.opsForValue().get("movie-api-v2:token:" + userToken.getUserEmail());

                // 没有这个账号的token
                if (tokenValue != null) {
                    // 上方的token是存在的，判断是否相等（解析出token里的账号是否和请求的token账号相同）
                    String email = JWTHS256.validToken(userToken.getTokenValue());

                    // 认证
                    if (userToken.getUserEmail().equals(email)) {
                        // 判断token值
                        if (tokenValue.equals(userToken.getTokenValue())) {
                            String newToken = tokenValue;
                            // token过期时间小于10分钟时，刷新token
                            if (new Date().getTime() - JWTHS256.getTokenExpireTime(tokenValue).getTime() > -600000) {
                                newToken = JWTHS256.buildJWT(email);
                            }

                            // VIP用户token时间长
                            if (userToken.getTokenType() == TokenType.VIP) {
                                userToken.setTtl(60 * 60);
                            }
                            stringRedisTemplate.opsForValue().set("movie-api-v2:token:" + userToken.getUserEmail(), newToken, Duration.ofSeconds(userToken.getTtl()));

                            apiResponse.setData(userToken.setTokenValue(newToken));
                            // 响应成功
                            flag = 2;
                        } else {
                            flag = 1;
                        }
                    } else {
                        // 认证失败
                        flag = 1;
                    }
                }
            } catch (Exception e) {
                flag = 1;
            }
        }
        // 认证成功，放行请求
        if (flag != 2) {
            request.getSession().setAttribute("flag", flag);
            response.sendRedirect("/api/v2/authorization");
        }
        return true;
    }

}
